package code.tools.bitmap
{
	import flash.display.Stage;
	import flash.events.TimerEvent;
	import flash.utils.Dictionary;
	import flash.utils.Timer;
	
	/**
	 * 驱动帧播放的类
	 * @author Yuri
	 */
	public class FrameDrive
	{
		private static var _stage:Stage;
		// 存储各个函数所对应的间隔帧数
		private static var listenerDic:Dictionary = new Dictionary();
		// 根据间隔帧来存储监听函数
		private static var listenersByWaitedFramesDic:Dictionary;
		private static var timer:Timer;
		
		/**
		 *一直存在,不受阻挡的 
		 */
		private static var godFrameDic:Dictionary;
		
		/**
		 *是否暂停 
		 */
		private static var _isPause:Boolean;
		public static function get stage():Stage
		{
			return _stage;
		}

		public static function set stage(value:Stage):void
		{
			_stage = value;
			timer = new Timer(17);
			timer.addEventListener(TimerEvent.TIMER, stageEnterFrame);
			timer.start();
			_isPause = false;
		}
		
		private static var _index:int = 0;
		private static var _godIndex:int = 0;
		
		//e.updateAfterEvent();暂且停用，如果有渲染不及时导致有误差要打开
		private static function stageEnterFrame(e:TimerEvent):void
		{
			if(!_isPause){
				if(listenersByWaitedFramesDic)
				{
					for (var waitedFrames:* in listenersByWaitedFramesDic)
					{
						if (_index % int(waitedFrames) == 0)
						{
							for each (var fn:Function in listenersByWaitedFramesDic[waitedFrames])
							{
								fn();
//								e.updateAfterEvent();
							}
						}
					}
				}
				_index++;
			}
			if(godFrameDic)
			{
				for (var waitedFramesA:* in godFrameDic)
				{
					if (_godIndex % int(waitedFramesA) == 0)
					{
						for each (var fnA:Function in godFrameDic[waitedFramesA])
						{
							fnA();
//							e.updateAfterEvent();
						}
					}
				}
			}
			_godIndex++;
		}
		
		/**
		 * 添加帧事件
		 * @param fn 回调函数
		 * @param interval 间隔
		 * @param isForever 是否一直存在，不会被打断
		 * 
		 */
		public static function addEventListener(fn:Function,interval:int = 33,isForever:Boolean=false):void
		{
			var frameRate:int = 1000 / interval;
			// 播放间隔帧数
			var waitedFrames:int = 60 / frameRate;
			removeListener(fn);
			listenerDic[fn] = waitedFrames;
			
			if(isForever){
				if(!godFrameDic) godFrameDic = new Dictionary();
				if (!godFrameDic[waitedFrames])
				{
					godFrameDic[waitedFrames] = [];
				}
				godFrameDic[waitedFrames].push(fn);
			}else{
				if(listenersByWaitedFramesDic == null)
				{
					listenersByWaitedFramesDic = new Dictionary();
				}
				if (!listenersByWaitedFramesDic[waitedFrames])
				{
					listenersByWaitedFramesDic[waitedFrames] = [];
				}
				listenersByWaitedFramesDic[waitedFrames].push(fn);
			}
		}
			
		
		public static function removeListener(fn:Function):void
		{
			if (listenerDic[fn])
			{
				var indexOfWasted:int;
				if (listenersByWaitedFramesDic && listenersByWaitedFramesDic[listenerDic[fn]])
				{
					indexOfWasted = (listenersByWaitedFramesDic[listenerDic[fn]] as Array).indexOf(fn);
					if (indexOfWasted != -1)
						(listenersByWaitedFramesDic[listenerDic[fn]] as Array).splice(indexOfWasted, 1);
				}
				if (godFrameDic && godFrameDic[listenerDic[fn]])
				{
					indexOfWasted = (godFrameDic[listenerDic[fn]] as Array).indexOf(fn);
					if (indexOfWasted != -1)
						(godFrameDic[listenerDic[fn]] as Array).splice(indexOfWasted, 1);
				}
				delete listenerDic[fn]; // or set null?
			}
		}
		
		public static function hasEventListener(fn:Function):Boolean{
			if (listenerDic[fn])
			{
				var indexOfWasted:int;
				if (listenersByWaitedFramesDic[listenerDic[fn]])
				{
					indexOfWasted = (listenersByWaitedFramesDic[listenerDic[fn]] as Array).indexOf(fn);
					if (indexOfWasted != -1)
						return true;
				}
				if (godFrameDic[listenerDic[fn]])
				{
					indexOfWasted = (godFrameDic[listenerDic[fn]] as Array).indexOf(fn);
					if (indexOfWasted != -1)
						return true;
				}
			}
			return false;
		}
		
		/**
		 *暂停 
		 * 
		 */
		public static function pause():void{
//			if(timer) timer.stop();
			_isPause = true;
		}
		
		public static function get isPause():Boolean{
			return _isPause;
		}
		
		/**
		 *播放 
		 * 
		 */
		public static function play():void{
//			if(timer) timer.start();
			_isPause = false;
		}
	}
}